﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Openlab.Tools.CodeGender.Classes
{
    public class EntityClass : Class
    {
        List<Column> columns;
        bool protobuf;

        public EntityClass(CodeOption option)
            : base(option.ClassName, option.ModelNamespaceName)
        {
            this.columns = option.Columns;
            this.protobuf = option.ProtoBuf;

            if (this.protobuf)
            {
                this.NameSpaces.Add("ProtoBuf");
                this.Attributes.Add("ProtoContract");
            }
        }

        public override string Body
        {
            get
            {
                StringBuilder code = new StringBuilder();
                StringBuilder code2 = new StringBuilder();

                code.AppendLine();
                code.AppendLineWithTabs("/// <summary>", 0);
                code.AppendLineFormatWithTabs("/// {0} OR映射构造函数", 0, Name);
                code.AppendLineWithTabs("/// </summary>", 0);
                code.AppendLineFormatWithTabs("public {0}(System.Data.IDataReader dr)", 0, Name);
                code.AppendLineWithTabs("{", 0);
                foreach (Column column in columns)
                {
                    string convert = string.Format(column.ConvertFormat,
                        string.Format("dr[\"{0}\"]", column.Name));
                    if (column.NullAble)
                    {
                        code.AppendLineFormatWithTabs("if(!Convert.IsDBNull(dr[\"{0}\"]))", 1, column.Name);
                        code.AppendLineFormatWithTabs("this.{0} = {1};", 2, column.Name == Name ? "_" + column.Name : column.Name, convert);
                    }
                    else
                    {
                        code.AppendLineFormatWithTabs("this.{0} = {1};", 1, column.Name == Name ? "_" + column.Name : column.Name, convert);
                    }
                }
                code.AppendLineWithTabs("}", 0);
                code.AppendLine();

                int i = 1;

                code.AppendLine("#region Members");
                code.AppendLine();

                foreach (Column column in columns)
                {
                    code.AppendLineFormatWithTabs("{0}{3} {1}{2};", 0, column.CSTypeName, column.Name.ToFirstLower(), GetDefaultValue(column.CSTypeName), (column.NullAble && column.CSTypeName != "string") ? "?" : string.Empty);

                    code2.AppendLineWithTabs("/// <summary>", 0);
                    code2.AppendLineFormatWithTabs("/// {1}: {0}", 0, column.Remarks, i);
                    code2.AppendLineWithTabs("/// </summary>", 0);
                    if (protobuf)
                        code2.AppendLineFormatWithTabs("[ProtoMember({0})]", 0, i);
                    code2.AppendLineFormatWithTabs("public {0}{3} {1} {{ get{{return {2};}} set{{{2}=value;}} }}", 0, column.CSTypeName, column.Name == Name ? "_" + column.Name : column.Name, column.Name.ToFirstLower(), (column.NullAble && column.CSTypeName != "string") ? "?" : string.Empty);

                    i++;
                }

                code.AppendLine();
                code.AppendLine("#endregion");

                code.AppendLine();
                code.Append(code2.ToString());

                return code.ToString();
            }
        }

        private string GetDefaultValue(string type)
        {
            switch (type)
            {
                case "string":
                    return " = string.Empty";
                case "Guid":
                    return " = Guid.Empty";
                default:
                    break;
            }

            return string.Empty;
        }
    }
}
